home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: x if (pormat, l/10/19 13:19:18 lhecking Exp $
- *
- */
-
- /* GNUPLOT - xref.c */
-
- /*[
- * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the complete modified source code. Modifications are to
- * be distributed as patches to the released version. Permission to
- * distribute binaries produced by compiling modified sources is granted,
- * provided you
- * 1. distribute the corresponding source modifications from the
- * released version in the form of a patch file along with the binaries,
- * 2. add special version identification to distinguish your version
- * in addition to the base release version number,
- * 3. provide your name and address as the primary contact for the
- * support of your modified version, and
- * 4. retain our contact information in regard to use of the base
- * software.
- * Permission to distribute the released version of the source code along
- * with corresponding source modifications in the form of a patch file is
- * granted with same provisions 2 through 4 for binary distributions.
- *
- * This software is provided "as is" without express or implied warranty
- * to the extent permitted by applicable law.
- ]*/
-
- /*
- * this file is used by doc2ipf, doc2html, doc2rtf and doc2info
- *
- * MUST be included after termdoc.c (since termdoc.c redefines fgets() )
- *
- * it contains functions needed to handle xrefs, most of them from
- * doc2rtf (most likely) by Maurice Castro
- * or doc2ipf by Roger Fearick
- * or doc2html by Russel Lang
- *
- * I have modified the functions a little to make them more flexible
- * (lookup returns list instead of list->line) or let them work with all
- * four programs (adding three parameters to refs).
- *
- * I switched the search order of lookup. Makes more sense to me
- *
- * Stefan Bodewig 1/29/1996
- */
-
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
-
- #define DOCS_XREF_MAIN
-
- #include "ansichek.h"
- #include "stdfn.h"
- #include "doc2x.h"
- #include "xref.h"
-
- struct LIST *list = NULL;
- struct LIST *head = NULL;
-
- struct LIST *keylist = NULL;
- struct LIST *keyhead = NULL;
-
- int maxlevel = 0; /* how deep are the topics nested? */
- int listitems = 0; /* number of topics */
-
- /* for debugging (invoke from gdb !) */
- void dump_list()
- {
- struct LIST *element = head;
- while (element) {
- fprintf(stderr, "%p level %d, line %d, \"%s\"\n", element, element->level, element->line, element->string);
- element = element->next;
- }
- }
-
-
- #ifdef PROTOTYPES
- void *xmalloc(size_t size)
- {
- void *p = malloc(size);
- #else
- char *xmalloc(size) /* think this is correct for K&R C */
- unsigned int size;
- {
- char *p = malloc(size);
- #endif
- if (p)
- return p;
- fprintf(stderr, "Malloc failed\n");
- exit(1);
- return NULL; /* HBB 980317: kill superfluous warnings */
- }
-
- /* scan the file and build a list of line numbers where particular levels are */
- void parse(a)
- FILE *a;
- {
- static char line[MAX_LINE_LEN+1];
- char *c;
- int lineno = 0;
- int lastline = 0;
-
- /* insert a special level 0 listitem
- * this one is the starting point for the table of contents in the html version
- * and the Top-Node of the info version.
- *
- * Added this to support multiple level 1 items. --SB
- */
- listitems = 1;
- head = (list = (struct LIST *) xmalloc(sizeof(struct LIST)));
- list->prev = NULL;
- list->line = 0;
- list->level = 0;
- /* I would prefer list->string = NULL, but don't know if free(NULL) is OK
- * with all supported plattforms. */
- list->string = (char *) xmalloc(1);
- list->next = NULL;
-
- while (get_line(line, sizeof(line), a)) {
- lineno++;
- if (isdigit((int)line[0])) { /* start of new section */
- listitems++;
-
- if (list == NULL) { /* impossible with the new level 0 item */
- head = (list = (struct LIST *) xmalloc(sizeof(struct LIST)));
- list->prev = NULL;
- } else {
- list->next = (struct LIST *) xmalloc(sizeof(struct LIST));
- list->next->prev = list;
- list = list->next;
- list->next = NULL;
- }
-
- list->line = lastline = lineno;
- list->level = line[0] - '0';
- list->string = (char *) xmalloc(strlen(line) + 1);
- c = strtok(&(line[1]), "\n");
- strcpy(list->string, c);
- list->next = NULL;
- if (list->level > maxlevel)
- maxlevel = list->level;
- }
- if (line[0] == '?') { /* keywords */
- if (keylist == NULL) {
- keyhead = (keylist = (struct LIST *) xmalloc(sizeof(struct LIST)));
- keylist->prev = NULL;
- } else {
- keylist->next = (struct LIST *) xmalloc(sizeof(struct LIST));
- keylist->next->prev = keylist;
- keylist = keylist->next;
- }
-
- keylist->line = lastline;
- keylist->level = list->level;
- c = strtok(&(line[1]), "\n");
- if (c == NULL || *c == '\0')
- c = list->string;
- keylist->string = (char *) malloc(strlen(c) + 1);
- strcpy(keylist->string, c);
- keylist->next = NULL;
- }
- }
- rewind(a);
- }
-
- /* look up a topic in text reference */
- /*
- * Original version from doc2rtf (|| ipf || html) scanned keylist before list.
- * This way we get a reference to `plot` for the topic `splot` instead
- * of one to `splot`. Switched the search order -SB.
- */
- struct LIST *
- lookup(s)
- char *s;
- {
- char *c;
- char tokstr[MAX_LINE_LEN+1];
- char *match;
- int l;
-
- strcpy(tokstr, s);
-
- /* first try titles */
- match = strtok(tokstr, " \n\t");
- if (match == NULL) {
- fprintf(stderr, "Error in lookup(\"%s\")\n", s);
-
- /* there should a line number, but it is local to parse() */
- fprintf(stderr, "Possible missing link character (`) near above line number\n");
- exit(3);
- }
- l = 0; /* level */
-
- list = head;
- while (list != NULL) {
- c = list->string;
- while (isspace((int)(*c)))
- c++;
- if (!strcmp(match, c)) {
- l = list->level;
- match = strtok(NULL, "\n\t ");
- if (match == NULL) {
- return (list);
- }
- }
- if (l > list->level)
- break;
- list = list->next;
- }
-
- /* then try the ? keyword entries */
- keylist = keyhead;
- while (keylist != NULL) {
- c = keylist->string;
- while (isspace((int)(*c)))
- c++;
- if (!strcmp(s, c))
- return (keylist);
- keylist = keylist->next;
- }
-
- return (NULL);
- }
-
- /*
- * find title-entry for keyword-entry
- */
- struct LIST *lkup_by_number(line)
- int line;
- {
- struct LIST *run = head;
-
- while (run->next && run->next->line <= line)
- run = run->next;
-
- if (run->next)
- return run;
- else
- return NULL;
- }
-
- /*
- * free the whole list (I never trust the OS -SB)
- */
- void list_free __PROTO((void))
- {
- struct LIST *run;
-
- for (run = head; run->next; run = run->next);
- for (run = run->prev; run; run = run->prev) {
- free(run->next->string);
- free(run->next);
- }
- free(head->string);
- free(head);
-
- for (run = keyhead; run->next; run = run->next);
- for (run = run->prev; run; run = run->prev) {
- free(run->next->string);
- free(run->next);
- }
- free(keyhead->string);
- free(keyhead);
- }
-
-
- /* search through the list to find any references */
- /*
- * writes a menu of all subtopics of the topic located at l
- * format must contain %s for the title of the subtopic and may contain
- * a %d for the line number of the subtopic (used by doc2html and doc2rtf
- * The whole menu is preceeded by start and gets the trailer end
- */
- void refs(l, f, start, end, format)
- int l;
- FILE *f;
- char *start, *end, *format;
- {
- int curlevel, i;
- char *c;
- int inlist = FALSE;
-
- /* find current line */
- list = head;
- while (list->line != l)
- list = list->next;
- curlevel = list->level;
- list = list->next; /* look at next element before going on */
-
- if (start != NULL && list != NULL) { /* don't wrie start if there's no menue at all */
- inlist = TRUE;
- fprintf(f, "%s", start);
- }
- while (list != NULL) {
- /* we are onto the next topic so stop */
- if (list->level == curlevel)
- break;
- /* these are the next topics down the list */
- if (list->level == curlevel + 1) {
- c = list->string;
- while (isspace((int)(*c)))
- c++; /* strip leading whitespace */
-
- if (format != NULL) {
- for (i = 0; format[i] != '%' && format[i] != '\0'; i++);
- if (format[i] != '\0') {
- if (format[i + 1] == 'd') {
- /* line number has to be printed first */
- fprintf(f, format, list->line, c);
- }
- else {
- ++i;
- for (; format[i] != '%' && format[i] != '\0'; i++);
- if (format[i] != '\0') /* line number is second */
- fprintf(f, format, c, list->line);
- else /* no line number at all */
- fprintf(f, format, c);
- }
- }
- }
- }
- list = list->next;
- }
- if (inlist && end) /* trailer */
- fprintf(f, "%s", end);
- }
-